﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rappelz.GameServer
{
    public class TerrainPropInfo
    {
        public enum PropType : int
        {
            Unused = 0,
            UseNAF = 1,
            UseNX3 = 2,
            SpeedTree = 3,
            NPC = 4,
        }

        public enum RenderType : int
        {
            General = 0,
            Building = 1,
        }

        public class PropInfo
        {
            public int nLineIndex;              // 0x0
            public PropType Type;               // 0x4
            public RenderType RenderType;       // 0x8
            public int nCategory;               // 0xC
            public float fVisibleRatio;           // 0x10
            public int nShadowFlag;             // 0x14
            public string strName;              // 0x18
            // 
            // Function       :     public void PROPINFO_STRUCT(const struct CTerrainPropInfo::PROPINFO_STRUCT &)
            // Function       :     public void CTerrainPropInfo::PROPINFO_STRUCT::PROPINFO_STRUCT()
            // Function       :     public void CTerrainPropInfo::PROPINFO_STRUCT::~PROPINFO_STRUCT()
            // Function       :     public struct CTerrainPropInfo::PROPINFO_STRUCT & operator=(const struct CTerrainPropInfo::PROPINFO_STRUCT &)
            // Function       :     public void * __vecDelDtor(unsigned int)

        }

// UserDefinedType: CTerrainPropInfo
// VTable         :   , Type:  *
// Function       :   public void CTerrainPropInfo(const class CTerrainPropInfo &)
// Function       :   public void CTerrainPropInfo::CTerrainPropInfo()
// Function       :   public void CTerrainPropInfo::~CTerrainPropInfo()

        public bool Initialize(string szPropInfoFileName)
        {

            this.Release();
            this.m_pPropInfo = new PropInfo[65535];
            m_pPropInfo.Initialize();

            List<string> TextLines = new List<string>();
            string strPropNum;
            string strPropName;

            try
            {
                System.IO.StreamReader bw = new System.IO.StreamReader(Globals.AppPath + "\\resource\\NewMap\\" +  szPropInfoFileName);
                String row = bw.ReadLine();
                while (row != null)
                {
//                    if(!String.IsNullOrEmpty(row) && !row.StartsWith(";") )
                        TextLines.Add(row);
                    row = bw.ReadLine();
                }
                bw.Close();
                bw.Dispose();
            }
            catch (System.Exception ex)
            {
            	Globals.Log.Fatal("Error Reading Map Info: {0} - {1}", szPropInfoFileName, ex);
                return false;
            }

            float fCurrentVisibleRatio = 1.0f;
            int ptype = 0;
            int rtype = 0;
            int sflag = 0;
            int line_num = 0;
            int nCurrentCategory = 0;
            string[] vars;

            foreach (string s in TextLines)
            {
                string[] lines = s.Split('=');
                line_num++;
                if(lines.Length < 2)
                    continue;
                switch(lines[0])
                {
                    case "CATEGORY":
                        nCurrentCategory = -1;
                        for(int i = 0; i < this.m_CategoryNames.Count; ++i)
                        {
                            if(m_CategoryNames[i] == lines[1])
                            {
                                nCurrentCategory = i;
                                break;
                            }
                        }
                        if(nCurrentCategory == -1)
                        {
                            nCurrentCategory = this.m_CategoryNames.Count;
                            this.m_CategoryNames.Add(lines[1]);
                        }
                        break;

                    case "VISIBLE_RATIO":
                        fCurrentVisibleRatio = Marshal.ToSingle(lines[1]);
                        if ( fCurrentVisibleRatio == 0.0f )
                            fCurrentVisibleRatio = 1.0f;
                        break;

                    case "RENDERTYPE":
                        switch(lines[1])
                        {
                            case "general":
                                rtype = 0;
                                break;

                            case "building":
                                rtype = 1;
                                break;
                        }
                        break;

                    case "PROPNAME":
                        vars = lines[1].Split(',');
                        if (vars.Length < 2)
                            continue;

                        strPropNum = vars[0];
                        strPropName = vars[1];

                        if (vars.Length == 4)
                        {
                            sflag = this.GetShadowFlag(vars[3]) | this.GetShadowFlag(vars[2]);
                        }
                        if (strPropNum.Length <= 0)
                            continue;

                        int prop_num = Marshal.ToInt32(strPropNum);
                        if (this.CheckPropFileType(strPropName, ".nx3"))
                        {
                            ptype = 2;
                        }
                        else if (this.CheckPropFileType(strPropName, "_default.naf"))
                        {
                            ptype = 1;
                        }
                        else if (this.CheckPropFileType(strPropName, ".spt"))
                        {
                            ptype = 3;
                        }
                        else
                        {
                            if ( !this.CheckPropFileType(strPropName, ".cob"))
                                continue;
                            ptype = 4;
                        }

                        this.SetPropInfo(line_num, (ushort)prop_num, (PropType) ptype, (RenderType)rtype, nCurrentCategory, fCurrentVisibleRatio, strPropName, sflag);
                        break;

                }
            }

            return true;
        }

        public void Release()
        {
            m_CategoryNames.Clear();
            m_pPropInfo = null;
        }
// Function       :   public const class std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & GetPropCategoryNames()
// Function       :   public enum CTerrainPropInfo::PROP_TYPE GetPropType(unsigned short)

        private int GetShadowFlag(string str)
        {
            if (str == "no_ca")
                return 1;
            if (str == "dy_ca")
                return 2;
            if (str == "st_ca")
                return 4;
            if (str == "no_re")
                return 8;
            if (str == "re")
                return 16;
            return 9;
        }

// Function       :   public int GetShadowFlag(unsigned short)
// Function       :   public enum CTerrainPropInfo::RENDER_TYPE GetPropRenderType(unsigned short)
// Function       :   public bool IsValidProp(unsigned short)
// Function       :   public int GetPropCategory(unsigned short)
// Function       :   public float GetPropVisibleRatio(unsigned short)
// Function       :   public const char * GetPropName(unsigned short)
// Function       :   public const char * GetPropFileName(unsigned short, bool)
// Function       :   public const int GetPropLineIndex(unsigned short)
// Function       :   public static class std::basic_string<char,std::char_traits<char>,std::allocator<char> > GetNX3NameByNAFName(const char *)

        public PropInfo[] m_pPropInfo;            // 0x4
        public List<string> m_CategoryNames = new List<string>();


        private bool CheckPropFileType(string rname, string szTail)
        {
            if (rname.Contains(szTail))
                return true;
            return false;
        }

        private void SetPropInfo(int nLineIndex, ushort wPropNum, TerrainPropInfo.PropType Type, TerrainPropInfo.RenderType RenderType, int nCategory, float fVisibleRatio, string rName, int nShadowFlag)
        {
            PropInfo p = new PropInfo();
            p.nLineIndex = nLineIndex;
            p.Type = Type;
            p.RenderType = RenderType;
            p.nCategory = nCategory;
            p.fVisibleRatio = fVisibleRatio;
            p.strName = rName;
            p.nShadowFlag = nShadowFlag;

            this.m_pPropInfo[wPropNum] = p;
        }
            
// Function       :   protected class KStream * GetResourceStream(const char *)
// Function       :   public class CTerrainPropInfo & operator=(const class CTerrainPropInfo &)
// Function       :   public void __local_vftable_ctor_closure()
// Function       :   public void * __vecDelDtor(unsigned int)

    }
}
